<?php
/**
 * ProfilesApi
 * PHP version 5
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 * @Tag v1.0.2
 */

/**
 * Amazon Ads API - Profiles
 *
 * Profiles represent an advertiser and their account's marketplace, and are used in all subsequent API calls via a management scope, `Amazon-Advertising-API-Scope`. Reports and all entity management operations are associated with a single profile. Advertisers cannot have more than one profile for each marketplace.  Advertisers who operate in more than one marketplace (for example, Amazon.com, Amazon.co.uk, Amazon.co.jp) will have only one profile associated with each marketplace. [**See this link**](https://advertising.amazon.com/API/docs/en-us/info/api-overview#api-endpoints) for a list of marketplaces associated with each endpoint.  To retrieve your profile IDs, call the listProfiles operation, and include a valid authorization access token in the header. Use a `profileId` from the returned list as the value for the management scope (`Amazon-Advertising-API-Scope`) in the headers for subsequent API calls.
 *
 * OpenAPI spec version: 3.0
 * 
 * Generated by:https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api.git
 * AmazonAdvertisingApi Codegen version: 3.0.51
 */
/**
 * NOTE: This class is auto generated by the AmazonAdvertisingApi code generator program.
 *https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 * Do not edit the class manually.
 */

namespace AmazonAdvertisingApi\Api;

use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use AmazonAdvertisingApi\ApiException;
use AmazonAdvertisingApi\ObjectSerializer;

/**
 * ProfilesApi Class Doc Comment
 *
 * @category Class
 * @package  AmazonAdvertisingApi
 * @author   vv_guo
 * @link    https://gitee.com/HuaLiLiDeDiDiao/amazon-advertising-api
 */
class ProfilesApi extends BaseApi
{

    /**
     * Operation getProfileById
     *
     * Gets a profile specified by identifier.
     *
     * @param  int $profile_id profile_id (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\Profile
     */
    public function getProfileById($profile_id)
    {
        list($response) = $this->getProfileByIdWithHttpInfo( $profile_id);
        return $response;
    }

    /**
     * Operation getProfileByIdWithHttpInfo
     *
     * Gets a profile specified by identifier.
     *
     * @param  int $profile_id (required)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\Profile, HTTP status code, HTTP response headers (array of strings)
     */
    public function getProfileByIdWithHttpInfo( $profile_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\Profile';
        $request = $this->getProfileByIdRequest($profile_id);
        $signedRequest = $this->config->signRequest(
            $request
        );
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($signedRequest, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Profile',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation getProfileByIdAsync
     *
     * Gets a profile specified by identifier.
     *
     * @param  int $profile_id (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getProfileByIdAsync( $profile_id)
    {
        return $this->getProfileByIdAsyncWithHttpInfo($profile_id)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation getProfileByIdAsyncWithHttpInfo
     *
     * Gets a profile specified by identifier.
     *
     * @param  int $profile_id (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function getProfileByIdAsyncWithHttpInfo( $profile_id)
    {
        $returnType = '\AmazonAdvertisingApi\Model\Profile';
        $request = $this->getProfileByIdRequest($profile_id);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'getProfileById'
     *
     * @param  int $profile_id (required)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function getProfileByIdRequest($profile_id)
    {
        // verify the required parameter 'profile_id' is set
        if ($profile_id === null || (is_array($profile_id) && count($profile_id) === 0)) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $profile_id when calling getProfileById'
            );
        }

        $resourcePath = '/v2/profiles/{profileId}';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // path params
        if ($profile_id !== null) {
            $resourcePath = str_replace(
                '{' . 'profileId' . '}',
                ObjectSerializer::toPathValue($profile_id),
                $resourcePath
            );
        }

        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation listProfiles
     *
     * Gets a list of profiles.
     *
     * @param  string $api_program Filters response to include profiles that have permissions for the specified Advertising API program only. Setting &#x60;apiProgram&#x3D;billing&#x60; filters the response to include only profiles to which the user and application associated with the access token have permission to view or edit billing information. (optional, default to campaign)
     * @param  string $access_level Filters response to include profiles that have specified permissions for the specified Advertising API program only. Currently, the only supported access level is &#x60;view&#x60; and &#x60;edit&#x60;. Setting &#x60;accessLevel&#x3D;view&#x60; filters the response to include only profiles to which the user and application associated with the access token have view permission to the provided api program. (optional, default to edit)
     * @param  string $profile_type_filter Filters response to include profiles that are of the specified types in the comma-delimited list. Default is all types. Note that this filter performs an inclusive AND operation on the types. (optional)
     * @param  string $valid_payment_method_filter Filter response to include profiles that have valid payment methods. Default is to include all profiles. Setting this filter to &#x60;true&#x60; returns only profiles with either no &#x60;validPaymentMethod&#x60; field, or the &#x60;validPaymentMethod&#x60; field set to &#x60;true&#x60;.  Setting this to &#x60;false&#x60; returns profiles with the &#x60;validPaymentMethod&#x60; field set to &#x60;false&#x60; only. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\Profile[]
     */
    public function listProfiles($api_program = 'campaign', $access_level = 'edit', $profile_type_filter = null, $valid_payment_method_filter = null)
    {
        list($response) = $this->listProfilesWithHttpInfo($api_program, $access_level, $profile_type_filter, $valid_payment_method_filter);
        return $response;
    }

    /**
     * Operation listProfilesWithHttpInfo
     *
     * Gets a list of profiles.
     *
     * @param  string $api_program Filters response to include profiles that have permissions for the specified Advertising API program only. Setting &#x60;apiProgram&#x3D;billing&#x60; filters the response to include only profiles to which the user and application associated with the access token have permission to view or edit billing information. (optional, default to campaign)
     * @param  string $access_level Filters response to include profiles that have specified permissions for the specified Advertising API program only. Currently, the only supported access level is &#x60;view&#x60; and &#x60;edit&#x60;. Setting &#x60;accessLevel&#x3D;view&#x60; filters the response to include only profiles to which the user and application associated with the access token have view permission to the provided api program. (optional, default to edit)
     * @param  string $profile_type_filter Filters response to include profiles that are of the specified types in the comma-delimited list. Default is all types. Note that this filter performs an inclusive AND operation on the types. (optional)
     * @param  string $valid_payment_method_filter Filter response to include profiles that have valid payment methods. Default is to include all profiles. Setting this filter to &#x60;true&#x60; returns only profiles with either no &#x60;validPaymentMethod&#x60; field, or the &#x60;validPaymentMethod&#x60; field set to &#x60;true&#x60;.  Setting this to &#x60;false&#x60; returns profiles with the &#x60;validPaymentMethod&#x60; field set to &#x60;false&#x60; only. (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\Profile[], HTTP status code, HTTP response headers (array of strings)
     */
    public function listProfilesWithHttpInfo( $api_program = 'campaign', $access_level = 'edit', $profile_type_filter = null, $valid_payment_method_filter = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\Profile[]';
        $request = $this->listProfilesRequest( $api_program, $access_level, $profile_type_filter, $valid_payment_method_filter);
        $signedRequest = $this->config->signRequest(
            $request
        );
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($signedRequest, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\Profile[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation listProfilesAsync
     *
     * Gets a list of profiles.
     *
     * @param  string $api_program Filters response to include profiles that have permissions for the specified Advertising API program only. Setting &#x60;apiProgram&#x3D;billing&#x60; filters the response to include only profiles to which the user and application associated with the access token have permission to view or edit billing information. (optional, default to campaign)
     * @param  string $access_level Filters response to include profiles that have specified permissions for the specified Advertising API program only. Currently, the only supported access level is &#x60;view&#x60; and &#x60;edit&#x60;. Setting &#x60;accessLevel&#x3D;view&#x60; filters the response to include only profiles to which the user and application associated with the access token have view permission to the provided api program. (optional, default to edit)
     * @param  string $profile_type_filter Filters response to include profiles that are of the specified types in the comma-delimited list. Default is all types. Note that this filter performs an inclusive AND operation on the types. (optional)
     * @param  string $valid_payment_method_filter Filter response to include profiles that have valid payment methods. Default is to include all profiles. Setting this filter to &#x60;true&#x60; returns only profiles with either no &#x60;validPaymentMethod&#x60; field, or the &#x60;validPaymentMethod&#x60; field set to &#x60;true&#x60;.  Setting this to &#x60;false&#x60; returns profiles with the &#x60;validPaymentMethod&#x60; field set to &#x60;false&#x60; only. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listProfilesAsync( $api_program = 'campaign', $access_level = 'edit', $profile_type_filter = null, $valid_payment_method_filter = null)
    {
        return $this->listProfilesAsyncWithHttpInfo( $api_program, $access_level, $profile_type_filter, $valid_payment_method_filter)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation listProfilesAsyncWithHttpInfo
     *
     * Gets a list of profiles.
     *
     * @param  string $api_program Filters response to include profiles that have permissions for the specified Advertising API program only. Setting &#x60;apiProgram&#x3D;billing&#x60; filters the response to include only profiles to which the user and application associated with the access token have permission to view or edit billing information. (optional, default to campaign)
     * @param  string $access_level Filters response to include profiles that have specified permissions for the specified Advertising API program only. Currently, the only supported access level is &#x60;view&#x60; and &#x60;edit&#x60;. Setting &#x60;accessLevel&#x3D;view&#x60; filters the response to include only profiles to which the user and application associated with the access token have view permission to the provided api program. (optional, default to edit)
     * @param  string $profile_type_filter Filters response to include profiles that are of the specified types in the comma-delimited list. Default is all types. Note that this filter performs an inclusive AND operation on the types. (optional)
     * @param  string $valid_payment_method_filter Filter response to include profiles that have valid payment methods. Default is to include all profiles. Setting this filter to &#x60;true&#x60; returns only profiles with either no &#x60;validPaymentMethod&#x60; field, or the &#x60;validPaymentMethod&#x60; field set to &#x60;true&#x60;.  Setting this to &#x60;false&#x60; returns profiles with the &#x60;validPaymentMethod&#x60; field set to &#x60;false&#x60; only. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function listProfilesAsyncWithHttpInfo( $api_program = 'campaign', $access_level = 'edit', $profile_type_filter = null, $valid_payment_method_filter = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\Profile[]';
        $request = $this->listProfilesRequest( $api_program, $access_level, $profile_type_filter, $valid_payment_method_filter);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'listProfiles'
     *
     * @param  string $api_program Filters response to include profiles that have permissions for the specified Advertising API program only. Setting &#x60;apiProgram&#x3D;billing&#x60; filters the response to include only profiles to which the user and application associated with the access token have permission to view or edit billing information. (optional, default to campaign)
     * @param  string $access_level Filters response to include profiles that have specified permissions for the specified Advertising API program only. Currently, the only supported access level is &#x60;view&#x60; and &#x60;edit&#x60;. Setting &#x60;accessLevel&#x3D;view&#x60; filters the response to include only profiles to which the user and application associated with the access token have view permission to the provided api program. (optional, default to edit)
     * @param  string $profile_type_filter Filters response to include profiles that are of the specified types in the comma-delimited list. Default is all types. Note that this filter performs an inclusive AND operation on the types. (optional)
     * @param  string $valid_payment_method_filter Filter response to include profiles that have valid payment methods. Default is to include all profiles. Setting this filter to &#x60;true&#x60; returns only profiles with either no &#x60;validPaymentMethod&#x60; field, or the &#x60;validPaymentMethod&#x60; field set to &#x60;true&#x60;.  Setting this to &#x60;false&#x60; returns profiles with the &#x60;validPaymentMethod&#x60; field set to &#x60;false&#x60; only. (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function listProfilesRequest( $api_program = 'campaign', $access_level = 'edit', $profile_type_filter = null, $valid_payment_method_filter = null)
    {
        $resourcePath = '/v2/profiles';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        if ($api_program !== null) {
            $queryParams['apiProgram'] = ObjectSerializer::toQueryValue($api_program, null);
        }
        // query params
        if ($access_level !== null) {
            $queryParams['accessLevel'] = ObjectSerializer::toQueryValue($access_level, null);
        }
        // query params
        if ($profile_type_filter !== null) {
            $queryParams['profileTypeFilter'] = ObjectSerializer::toQueryValue($profile_type_filter, null);
        }
        // query params
        if ($valid_payment_method_filter !== null) {
            $queryParams['validPaymentMethodFilter'] = ObjectSerializer::toQueryValue($valid_payment_method_filter, null);
        }

        // body params
        $_tempBody = null;

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                []
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'GET',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation updateProfiles
     *
     * Update the daily budget for one or more profiles.
     *
     * @param  \AmazonAdvertisingApi\Model\Profile[] $body body (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return \AmazonAdvertisingApi\Model\ProfileResponse[]
     */
    public function updateProfiles($body = null)
    {
        list($response) = $this->updateProfilesWithHttpInfo($body);
        return $response;
    }

    /**
     * Operation updateProfilesWithHttpInfo
     *
     * Update the daily budget for one or more profiles.
     *
     * @param  \AmazonAdvertisingApi\Model\Profile[] $body (optional)
     *
     * @throws \AmazonAdvertisingApi\ApiException on non-2xx response
     * @throws \InvalidArgumentException
     * @return array of \AmazonAdvertisingApi\Model\ProfileResponse[], HTTP status code, HTTP response headers (array of strings)
     */
    public function updateProfilesWithHttpInfo($body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\ProfileResponse[]';
        $request = $this->updateProfilesRequest($body);
        $signedRequest = $this->config->signRequest(
            $request
        );
        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($signedRequest, $options);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? $e->getResponse()->getBody()->getContents() : null
                );
            }

            $statusCode = $response->getStatusCode();

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    $response->getBody()
                );
            }

            $responseBody = $response->getBody();
            if ($returnType === '\SplFileObject') {
                $content = $responseBody; //stream goes to serializer
            } else {
                $content = $responseBody->getContents();
                if (!in_array($returnType, ['string','integer','bool'])) {
                    $content = json_decode($content);
                }
            }

            return [
                ObjectSerializer::deserialize($content, $returnType, []),
                $response->getStatusCode(),
                $response->getHeaders()
            ];

        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\AmazonAdvertisingApi\Model\ProfileResponse[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    break;
            }
            throw $e;
        }
    }

    /**
     * Operation updateProfilesAsync
     *
     * Update the daily budget for one or more profiles.
     *
     * @param  \AmazonAdvertisingApi\Model\Profile[] $body (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateProfilesAsync( $body = null)
    {
        return $this->updateProfilesAsyncWithHttpInfo( $body)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation updateProfilesAsyncWithHttpInfo
     *
     * Update the daily budget for one or more profiles.
     *
     * @param  \AmazonAdvertisingApi\Model\Profile[] $body (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function updateProfilesAsyncWithHttpInfo( $body = null)
    {
        $returnType = '\AmazonAdvertisingApi\Model\ProfileResponse[]';
        $request = $this->updateProfilesRequest( $body);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    $responseBody = $response->getBody();
                    if ($returnType === '\SplFileObject') {
                        $content = $responseBody; //stream goes to serializer
                    } else {
                        $content = $responseBody->getContents();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'updateProfiles'
     *
     * @param  \AmazonAdvertisingApi\Model\Profile[] $body (optional)
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    protected function updateProfilesRequest( $body = null)
    {
        $resourcePath = '/v2/profiles';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;


        // body params
        $_tempBody = null;
        if (isset($body)) {
            $_tempBody = $body;
        }

        if ($multipart) {
            $headers = $this->headerSelector->selectHeadersForMultipart(
                ['application/json']
            );
        } else {
            $headers = $this->headerSelector->selectHeaders(
                ['application/json'],
                ['application/json']
            );
        }

        // for model (json/xml)
        if (isset($_tempBody)) {
            // $_tempBody is the method argument, if present
            $httpBody = $_tempBody;
            // \stdClass has no __toString(), so we should encode it manually
            if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($httpBody);
            }
        } elseif (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $multipartContents[] = [
                        'name' => $formParamName,
                        'contents' => $formParamValue
                    ];
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);

            } elseif ($headers['Content-Type'] === 'application/json') {
                $httpBody = \GuzzleHttp\json_encode($formParams);

            } else {
                // for HTTP post (form)
                $httpBody = \GuzzleHttp\Psr7\Query::build($formParams);
            }
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $query = \GuzzleHttp\Psr7\Query::build($queryParams);
        return new Request(
            'PUT',
            $this->config->getHost() . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }
}
